home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Apple II Sample Code / MPW IIGS SC / SC.020.DTS.Tools.Libs / fakeModalDialog.aii < prev    next >
Encoding:
Text File  |  1990-06-24  |  46.0 KB  |  2,158 lines  |  [TEXT/MPS ]

  1. *******************************************************************************
  2. *
  3. * fakeModalDialog and other supporting access routines and such.
  4. * Version 3.0
  5. *
  6. * Copyright (c)
  7. * Apple Computer, Inc.  1989-1990
  8. * All Rights Reserved.
  9. *
  10. * Written by Eric Soldan.
  11. *
  12. * Developer Technical Support Apple II Sample Code
  13. *
  14. * The purpose of this code is to handle dialogs in a variety of ways
  15. * that are more robust than what the toolbox offers.  It also supports
  16. * the new movable/modeless dialog types described in the latest human
  17. * interface guidelines.
  18. *
  19. *******************************************************************************
  20. *
  21. * Here is some C sample code that uses fakeModalDialog.  This code is
  22. * for an about box.  What is different about this about box is that
  23. * you can use menus while the about box is on the screen.  This means
  24. * that you can use desk accessories while the about box is active.
  25. * It also means that you can quit the application at this time.
  26. * You can also close the about box with the close menu option.
  27. *
  28. * This sample uses the modal mode with menus for the about box.  Since
  29. * menus are available, there is more support (code) necessary from the
  30. * application.  The application has to detect that the user chose
  31. * close from the menu and take appropriate action, for example.
  32. *
  33. * First, a little about fakeModalDialog:
  34. *
  35. * fakeModalDialog returns a long as a result.
  36. * If the result is NULL:
  37. *     Nothing happened.  Unlike ModalDialog, control is returned to
  38. *     the application during null events.  This is so the application
  39. *     can do stuff like switch cursors, or other idle tasks.
  40. * If bit 31 of the result is true:
  41. *     The user chose a menu item.  Bits 0-15 are the menu item ID.
  42. *                                  Bits 16-30 are the menu ID.
  43. * If bit 31 of the result is false:
  44. *     The user clicked on a control.  Bits 0-30 are the control ID.
  45.  
  46. * Now, the sample code fragment:
  47.  
  48. *   #define aboutBoxID 0x1001L
  49. *
  50. *   void    doAboutBox()
  51. *   {
  52. *       WindowPtr       wptr, keepPort;
  53. *       unsigned long   id;
  54. *       unsigned int    item;
  55. *       keepPort = GetPort();   /* Preserve the current port. */
  56. *
  57. *       wptr = NewWindow2(NULL, NULL, NULL, NULL, 2, aboutBoxID, rWindParam1);
  58. *           /* Open the about box from a resource. */
  59. *
  60. *       if (!_toolErr) {            /* If the window opened successfully... */
  61. *           aboutWindow = wptr;     /* Set the aboutWindow global variable. */
  62. *                                   /* This tells other routines what state */
  63. *                                   /* we are in.                           */
  64. *
  65. *           for (;;) {      /* Loop, due to NULL events being returned. */
  66. *
  67. *               id = fakeModalDialog(
  68. *                   &event,         /* Pointer to extended event record.   */
  69. *                   NULL,           /* Use default update procedure.       */
  70. *                   NULL,           /* There will be no event mods.        */
  71. *                   NULL,           /* Do standard beep.                   */
  72. *                   fmdMenuSelect+  /* Allow pullDowns.                    */
  73. *                   fmdMenuKey+     /* Allow menu keys.                    */
  74. *                   fmdDeskAcc+     /* Allow desk accessories.             */
  75. *                   fmdUpdateAll    /* Update all windows, not just about. */
  76. *               );
  77. *
  78. *               item = id;          /* Get lo-word from result. */
  79. *
  80. *               if (id & 0x80000000L) {             /* If menu command...    */
  81. *                   if (item == 255) {              /* If close command then */
  82. *                       HiliteMenu(0, FileMenuID);  /* turn menu inv. off.   */
  83. *                       break;                      /* Go close about box.   */
  84. *                   }
  85. *                   doMenuCommand(id);      /* Do other menus (like quit).   */
  86. *                   if (quitFlag) break;    /* User did do a quit from menu. */
  87. *               }
  88. *               else {                          /* ...else handle controls. */
  89. *                   if (item == 1) break;       /* User clicked OK button.  */
  90. *               }
  91. *           }
  92. *
  93. *           SetPort(keepPort);      /* Put port back before closing about. */
  94. *           CloseWindow(wptr);      /* Close aboutBox.                     */
  95. *           aboutWindow = NULL;     /* Let others know it is closed.       */
  96. *           appSetMenus();          /* Update the menus to reflect a new.  */
  97. *       }                           /* top window.                         */
  98. *   }
  99.  
  100. * An interesting point here is the call to appSetMenus.  This is a routine
  101. * in the application that is responsible for putting the menus in the
  102. * correct state.  fakeModalDialog automatically calls this routine (if told
  103. * to) whenever an activate event occurs that it gets a chance to see.
  104. * fakeModalDialog may not see the activate event  only if a desk accessory
  105. * is open, just behind the about box.  When the about box is closed, the
  106. * desk accessory gets the activate event.  fakeModalDialog never got an
  107. * activate event, so it didn't know to call the menu update routine.  This
  108. * situation can only occur when a desk accessory is just behind the window
  109. * to be closed.  As a safe rule, whenever a window is closed, the menu
  110. * update routine should be called by the application.  (Something like this
  111. * should be done anyway.)
  112.  
  113. * To tell fakeModalDialog to automatically call a menu update routine when
  114. * it gets an activate event, make a call to fmdSetMenuProc.  For an application
  115. * menu update routine called appSetMenus, you would tell fakeModalDialog
  116. * about it by the following:
  117. *     fmdSetMenuProc(appSetMenus);
  118. * To turn off menu updating again, do this:
  119. *     fmdSetMenuProc(NULL);
  120.  
  121. * fmdEditMenu figures the state of cut, copy, paste, and clear in
  122. * the edit menu based on the state of controls in the window.
  123. * It looks up the target control (either lineEdit or textEdit) and
  124. * then sets the states appropriately.  For lineEdit, if anything
  125. * is selected, then cut, copy and clear are available.  If there is
  126. * anything in the scrap, then paste is also available.  TextEdit 
  127. * works the same way, unless the textEdit control is a read-only
  128. * control.  In that case, cut, paste, and clear are not available.
  129. * If there is no lineEdit or textEdit control, then the state of
  130. * these menu items is left alone.  The application needs to take care
  131. * of them in that case.  (It is possible that there are custom
  132. * controls for the application that can use these menu items, and
  133. * there is no way for fakeModalDialog to know about them.  Therefore
  134. * the correct thing to do is to do nothing.)
  135.  
  136. * fmdFindCursorCtl is used to find which control is at a certain point.
  137. * The toolbox call FindControl can't be used for this because textEdit
  138. * controls become active when called with a point in them.  That is not
  139. * the desired effect of fmdFindCursorCtl.  If you just want to know what
  140. * control you are over and have nothing affected, then use this entry
  141. * point.  It is used by fakeModalDialog to determine whether or not to
  142. * display an i-beam cursor.  If the i-beam bit is set and the user moves
  143. * the mouse over a lineEdit or textEdit control, then the cursor changes
  144. * to an i-beam.  Note that the scrollbars for a textEdit control are
  145. * considered a separate control.  This is so that the cursor stays
  146. * an arrow when over the scrollbars.
  147.  
  148. * Back to fakeModalDialog:
  149.  
  150. * Some sample calls (in C) would look like:
  151. *   ctlID = fakeModalDialog(&event, NULL, NULL, NULL, 0);
  152. *   ctlID = fakeModalDialog(&event, updateProc, NULL, -1L, 0);
  153. *   ctlID = fakeModalDialog(&event, updateProc, eventHook, beepProc, flags);
  154. *
  155. * The parameters are:
  156. *
  157. * event:          A pointer to an extended (for 5.0) event record.
  158. * updateProc:     Pointer to function to update the window.  Pass a NULL for
  159. *                 default.  (The default entry point is called fmdStdDrawProc.)
  160. * eventHook:      Pointer to function that is called after the GetNextEvent
  161. *                 call and before any processing occurs on that event.  This
  162. *                 is more useful than a filter.  You can simply change the
  163. *                 event by changing the event record.  For example:  Let's say
  164. *                 that you want to be able to cancel a modal dialog by pressing
  165. *                 either openApple-period or ESC.  The problem is that,
  166. *                 although you can have two key equivalents for a
  167. *                 super-control, theway that modifiers are determined is the
  168. *                 same for both keys.  This means that you can't have
  169. *                 openApple-period and ESC asyour two key equivalents.  With
  170. *                 this event hook, you can lookat the event, and if it is the
  171. *                 openApple-period, you can simply change the event record so
  172. *                 that it is an ESC with no openApple modifier.  Then when you
  173. *                 return to fakeModalDialog, it will handle the event as if the
  174. *                 user simply typed an ESC.  By using this technique, you can
  175. *                 have as many modifiers as you want.  If you wish to filter
  176. *                 out an event, you would simply changethe event type to a
  177. *                 NULL event.
  178. * beepProc:       Pointer to custom beep function.  fakeModalDialog calls this
  179. *                 if there is any mouseDown outside the window, just like
  180. *                 ModalDialog.If you wish it to beep like ModalDialog, pass a
  181. *                 NULL.  If you wish it to do nothing, pass a -1.
  182. *                 If you wish a custom beep function, pass it a pointer to
  183. *                 that function.
  184. * flags, bit 0:   Cut/Copy/Paste for lineEdit items would normally involve
  185. *                 the scrap.  When this bit is true, the scrap is not involved
  186. *                 when using lineEdit items.  This may be useful to protect a
  187. *                 large scrap for an application from being hit with something
  188. *                 trivial.
  189. *        bit 1:   If true, allow menu pullDowns for movable/modal dialogs.
  190. *                 If they are allowed, then the return value is the menu
  191. *                 item ID (low-word) and the menu ID (hi-word).  To
  192. *                 distinguish from ctlID's, thehi-bit (bit 31) is set.  This
  193. *                 means that if you are allowing menu selections, you can't have
  194. *                 any menu ID's with a hi-bit-on ID.  It also means that you
  195. *                 can't have controls with bit 31 on either.
  196. *        bit 2:   If true, allow menu keys.  Return values work the same as for
  197. *                 pullDowns.
  198. *        bit 3:   If true, use i-beam cursor for lineEdit & textEdit ctls.
  199. *                 Otherwise, use an arrow cursor everywhere.
  200. *        bit 4:   If true, automatically handle desk accessories.  This means
  201. *                 that bit 1 must be true to have fakeModalDialog open the DA.
  202. *                 If the DA is already open, the user can click on it, and it
  203. *                 will become active, even if bit 1 is false.
  204. *        bit 14:  If true, update all windows.  The toolbox call ModalDialog
  205. *                 does not update other windows.  This takes away a lot of the
  206. *                 point of movable/modal dialogs.  The whole point is so that
  207. *                 you can see what is behind it.  When you move the dialog, if
  208. *                 the windows in back didn't update, then there would be no
  209. *                 point in moving the window.  If you want, you can set this
  210. *                 bit false, and it will update only the front-most
  211. *                 application window.
  212. *        bit 15:  This is the bit that determines whether or not a dialog is
  213. *                 movable.  If it is true, then the dialog is movable.  To be
  214. *                 moved, however, it has to have a title bar (the drag region)
  215. *                 and it has to have the fMove bit set.  Without these also,
  216. *                 the window still won't be able to be moved.
  217. *                 
  218. * ctlID:          Control that was hit, or menu that was chosen.
  219. *                 bit 31 off, it is a control ID.
  220. *                 bit 31 on, it is a menu ID (hi-word), menu item ID (lo-word).
  221. *
  222. * There is one more thing to worry about, and that is the border of the window.
  223. * The window manager doesn't allow you have an alert frame and a title at the
  224. * same time.  If you set both of these bits in the wFrameBits field, then the
  225. * alert border is drawn wrong.  It would be ideal for fakeModalDialog if this
  226. * restriction didn't exist.  Then the window attributes all could be chosen via
  227. * the window frame bits in a resource.  Unfortunately, this isn't the case.  To
  228. * manage this restriction, the default update procedure, under certain
  229. * conditions, draws the alert frame itself.  If fAlert is set, then the alert
  230. * border isn't drawn by the default update procedure.  The update procedure
  231. * doesn't have to draw it, since it is automatically drawn by the window
  232. * manager.  If fAlert is set, then the dialog doesn't have a title bar, due to
  233. * the window manager restriction.  If fAlert isn't set, then the default update
  234. * procedure draws the alert border.  The alert border is drawn as part of the
  235. * content of the window.  Due to this, the coordinates you use for the content
  236. * of the window have to be a little different, to make space for the border.
  237. * The upper-left-hand corner of the window is really 10,4, (4,4 for 320 mode)
  238. * instead of 0,0.  So far, we have discussed how the alert border gets drawn,
  239. * either by the window manager, or by the default update procedure for
  240. * fakeModalDialog.  It is possible that you don't want an alert border at all.
  241. * If you don't, then fAlert should be off, and you should turn on fFlex.  fFlex
  242. * was used because it should be able to be set from a resource, and all other
  243. * bits would have an adverse effect.  Dialogs don't have grow boxes and zoom
  244. * boxes, so fFlex is meaningless for dialogs (until now).
  245.  
  246. ***********************************************************************
  247.  
  248.     case on
  249.  
  250.     INCLUDE 'm16.util2'
  251.     INCLUDE 'e16.types'
  252.  
  253.     INCLUDE 'e16.control'
  254.     INCLUDE 'm16.control'
  255.     INCLUDE 'm16.desk'
  256.     INCLUDE 'e16.event'
  257.     INCLUDE 'm16.event'
  258.     INCLUDE 'e16.lineedit'
  259.     INCLUDE 'm16.lineedit'
  260.     INCLUDE 'm16.memory'
  261.     INCLUDE 'm16.menu'
  262.     INCLUDE 'm16.misctool'
  263.     INCLUDE 'm16.quickdraw'
  264.     INCLUDE 'm16.scrap'
  265.     INCLUDE 'm16.textedit'
  266.     INCLUDE 'e16.window'
  267.     INCLUDE 'm16.window'
  268.  
  269.     longi on
  270.     longa on
  271.  
  272. ***********************************************************************
  273.  
  274. fmdNoScrapForLE    equ $0001
  275. fmdMenuSelect    equ $0002
  276. fmdMenuKey    equ $0004
  277. fmdIBeam    equ $0008
  278. fmdDeskAcc    equ $0010
  279. fmdUpdateAll    equ $4000
  280. fmdMovable    equ $8000
  281.  
  282.     export fakeModalDialog
  283. fakeModalDialog    PROC
  284.     export FAKEMODALDIALOG
  285.     export fmdGetCtlPart, FMDGETCTLPART
  286.     import fmdEditMenu, fmdFindCursorCtl
  287.     import fmdStdDrawProc, fmdGetMenuProc
  288.     import fmdIBeamCursor, fmdGetIBeamAdr
  289.     import _fmdNoError
  290.  
  291.     DefineStack
  292.  
  293. dlgwptr    long    ;Must be at 1,s
  294. keepPort    long    ;Must be at 5,s
  295. ctlHndl    long
  296. ctlPtr    long
  297. theHndl    long
  298. thePtr    long
  299. whichWindow    long
  300. tempwptr    long
  301. code    word
  302. editTask    word
  303. yloc    word
  304. xloc    word
  305. wkind    word
  306. menunum    word
  307. zero    word
  308.  
  309. sizeLocals    EndLocals
  310.  
  311. saveDPage    word
  312. returnAddr    block 3
  313.  
  314.     BegParms
  315. flags    word    ;bit 0 = 0, involve scrap for
  316.         ;           lineEdit items.
  317.         ;bit 0 = 1, don't involve scrap for
  318.         ;           lineEdit items.
  319.         ;bit 1 = 0, don't do _MenuSelect for
  320.         ;           movable/modal dialogs.
  321.         ;bit 1 = 1, do _MenuSelect for
  322.         ;           movable/modal dialogs.
  323.         ;bit 2 = 0, don't do _MenuKey for
  324.         ;           movable/modal dialogs.
  325.         ;bit 2 = 1, do _MenuKey for
  326.         ;           movable/modal dialogs.
  327.         ;bit 3 = 0, use arrow cursor
  328.         ;           everywhere.
  329.         ;bit 3 = 1, use i-beam cursor for
  330.         ;           lineEdit & textEdit ctls.
  331.         ;bit 4 = 0, let app handle desk
  332.         ;           accessories.
  333.         ;bit 4 = 1, automatically handle desk
  334.         ;           accessories.
  335.         ;bit 14 = 0, Don't update other
  336.         ;            application windows.
  337.         ;bit 14 = 1, Update all windows.
  338.         ;bit 15 = 0, Modal window.
  339.         ;bit 15 = 1, movable/modal window.
  340. beepProc    long    ;Null, SysBeep.  Negative, do nothing.
  341. eventHook    long    ;Optional -- pass a NULL for none.
  342. updateProc    long    ;Optional -- pass a NULL for default.
  343. event    long    ;Must be extended 5.0 event rec ptr.
  344. sizeParms    EndParms
  345.  
  346. retval    long    ;Control ID hit.  NULL if none.
  347.         ;If bit 31 is on, then retval
  348.         ;is a menu ID.
  349. ***
  350.  
  351. FAKEMODALDIALOG    phd    ;Save directPage register.
  352.     tsc    ;Make space for locals.
  353.     sec
  354.     sbc #sizeLocals
  355.     tcs
  356.     tcd    ;Set directPage register.
  357.  
  358.     pla
  359.     pla
  360.     _GetPort    ;Result space already there (keepPort).
  361.  
  362.     pha
  363.     pha
  364.     _FrontWindow    ;Result space already there (dlgwptr).
  365.  
  366.     pha    ;Find out if it is a DA window.
  367.     pei dlgwptr+2
  368.     pei dlgwptr
  369.     _GetWKind
  370.     pla
  371.     sta wkind
  372.     bpl @gotit
  373.  
  374. @get1stRegWnd    pha    ;Result space for _GetWFrame.
  375.  
  376.     pha    ;Result space for _GetNextWindow.
  377.     pha
  378.  
  379.     pei dlgwptr+2
  380.     pei dlgwptr
  381.     _GetNextWindow
  382.  
  383.     lda 1,s    ;Param for _GetWFrame.
  384.     sta dlgwptr
  385.     lda 3,s
  386.     sta dlgwptr+2
  387.  
  388.     _GetWFrame
  389.     pla
  390.  
  391.     and #fVis
  392.     beq @get1stRegWnd    ;Window is invisible, so skip it.
  393.  
  394.     pha
  395.     pei dlgwptr+2
  396.     pei dlgwptr
  397.     _GetWKind
  398.     pla
  399.     bmi @get1stRegWnd    ;Window is system window, so skip it.
  400.  
  401. @gotit    stz retval    ;Assume nothing interesting is
  402.     stz retval+2    ;going to happen.
  403.     stz code
  404.     stz editTask    ;For cut/copy/paste/clear signal.
  405.     stz zero    ;For optimization purposes.
  406.  
  407.     lda updateProc+1    ;Set up the update procedure for all
  408.     bne @a    ;cases.  This also sets it up so that
  409.         ;TaskMaster can handle this window
  410.         ;from other parts of the application.
  411.  
  412.     lda #fmdStdDrawProc>>16
  413.     sta updateProc+2
  414.     lda #fmdStdDrawProc
  415.     sta updateProc    ;Use the default update procedure.
  416. @a    pei updateProc+2
  417.     pei updateProc
  418.     pei dlgwptr+2
  419.     pei dlgwptr
  420.     _SetContentDraw    ;Let the window and TaskMaster know.
  421.  
  422. @aa    pha    ;Make sure that top window is
  423.     pha    ;the active window.
  424.     _GetPort
  425.     pla
  426.     sta keepPort
  427.     pla
  428.     sta keepPort+2
  429.     pei dlgwptr+2
  430.     pei dlgwptr
  431.     _SetPort
  432.  
  433.     lda flags
  434.     and #fmdIBeam
  435.     beq @b    ;No cursor changes.
  436.  
  437.     lda wkind
  438.     bmi @b
  439.  
  440.     pha    ;Result space for control part.
  441.  
  442.     ldy #0    ;Point to where to put the handle.
  443.     phy
  444.     tdc
  445.     clc
  446.     adc #ctlHndl
  447.     pha    ;Pointer to ctlHndl now on stack.
  448.  
  449.     phy
  450.     adc #yloc-ctlHndl
  451.     pha    ;Pointer to yloc now on stack.
  452.     _GetMouse
  453.  
  454.     pei xloc    ;Now that they are right, pass 'em on.
  455.     pei yloc
  456.     pei dlgwptr+2
  457.     pei dlgwptr
  458.     jsl fmdFindCursorCtl ;Find which control cursor is over.
  459.     pla    ;The part code, which we don't care
  460.         ;about here.
  461.  
  462.     beq @arrowCursor    ;Not over any control -- use arrow.
  463.  
  464.     jsr getCtlProc    ;Find out what kind of control it is.
  465.     cmp #editTextControl>>16
  466.     beq @ibeamCursor    ;It is a TextEdit ctl, kind of
  467.         ;See fmdFindCursorCtl for more info.
  468.     cmp #editLineControl>>16
  469.     beq @ibeamCursor    ;It is a LineEdit tool.
  470.  
  471. @arrowCursor    jsr ibeamTest
  472.     bcc @b
  473.     _InitCursor
  474.     bra @b    ;We have an arrow cursor.
  475.  
  476. @ibeamCursor    jsr ibeamTest
  477.     bcs @b    ;We have an ibeam cursor.
  478.     jsl fmdIBeamCursor
  479.  
  480. @b    _SystemTask
  481.  
  482.     lda flags    ;See if cut/copy/paste is tied to menu.
  483.     and #fmdMenuSelect+fmdMenuKey
  484.     beq @c    ;Isn't keyDownEvt or mouseDownEvt.
  485.     jsl fmdEditMenu    ;Update the edit menu.
  486.  
  487. @c    pha    ;Get the event.
  488.     pea $FFFF
  489.     pei event+2
  490.     pei event
  491.     _GetNextEvent
  492.     pla
  493.     beq @exit    ;Event shouldn't be handled by app.
  494.  
  495.     ldy #owhat
  496.     lda [event],y
  497.     sta code
  498.     bne @gotEvent
  499.  
  500. @exit    lda code    ;See if code is 0.  If it is, force a
  501.     bne @exit0    ;NULL event, so the cursor will flash
  502.     ldy #owhat    ;for lineedit items, etc.
  503.     sta [event],y
  504.     pha
  505.     pea 1
  506.     pha
  507.     pha
  508.     pei event+2
  509.     pei event
  510.     _SendEventToCtl
  511.     pla
  512.  
  513. @exit0    pei keepPort+2
  514.     pei keepPort
  515.     _SetPort
  516.     tsc    ;Get rid of local variables.
  517.     clc
  518.     adc #sizeLocals
  519.     tcs
  520.     pld    ;Restore directPage register.
  521.     lda 1,s    ;Move return address.
  522.     sta 1+sizeParms,s
  523.     lda 2,s
  524.     sta 2+sizeParms,s
  525.     tsc    ;Get rid of passed parameters.
  526.     adc #sizeParms
  527.     tcs
  528.     jml _fmdNoError
  529.  
  530. @gotEvent    lda eventHook+1
  531.     beq @noEventHook    ;Zero, no event massaging.
  532.  
  533.     pei event+2    ;Give the event hook something
  534.     pei event    ;to play with.
  535.     phk    ;Push where we want to return to.
  536.     pea @noEventHook-1
  537.  
  538.     pha    ;Push the eventHook address and return
  539.     phb    ;to it.
  540.     pla
  541.     lda eventHook
  542.     dec a
  543.     pha
  544.     rtl
  545.  
  546. @noEventHook    ldy #owhat
  547.     lda [event],y
  548.     sta code
  549.  
  550.     jsr doMouseDown
  551.     bcc @exit
  552.  
  553.     jsr doMenuKey
  554.     bcc @exit    ;The key was a menu key.
  555.  
  556.     jsr doCutCopyPaste
  557.     bcc @exit    ;We did a cut, copy, or paste.
  558.  
  559.     jsr doActivate
  560.     bcc @exit    ;We did an activate.
  561.  
  562.     jsr doUpdate
  563.     bcc @exit    ;We did an update.
  564.  
  565.     pha
  566.     lda #0
  567.     pha
  568.     pha
  569.     pha
  570.     pei event+2
  571.     pei event
  572.     _SendEventToCtl
  573.     pla
  574.     beq @exit0
  575.  
  576.     ldy #owmTaskData2    ;Get the ctl hndl of affected ctl.
  577.     lda [event],y
  578.     sta ctlHndl    ;Save this in ctlHndl.
  579.     iny
  580.     iny
  581.     lda [event],y
  582.     sta ctlHndl+2
  583.     jsr setValues
  584.     brl @exit
  585.  
  586. ***
  587.  
  588. doCutCopyPaste    lda editTask    ;We already have a task, 
  589.     bne @atask    ;so don't check keypress.
  590.  
  591.     lda code
  592.     cmp #keyDownEvt
  593.     beq @akey
  594.     cmp #autoKeyEvt
  595.     beq @akey
  596.  
  597. @secexit    sec
  598.     rts
  599.  
  600. @akey    lda flags
  601.     and #fmdMenuKey
  602.     bne @secexit
  603.     ldy #omodifiers    ;See if it is a cut/copy/paste command.
  604.     lda [event],y
  605.     and #controlKey+optionKey+appleKey
  606.     cmp #appleKey
  607.     bne @secexit    ;Wrong modifiers -- no go.
  608.  
  609.     ldy #omessage
  610.     lda [event],y
  611.     ora #$20    ;Lower-case it.
  612.  
  613.     ldx #251
  614.     cmp #'x'
  615.     beq @yes
  616.     inx
  617.     cmp #'c'
  618.     beq @yes
  619.     inx
  620.     cmp #'v'
  621.     sec
  622.     bne @secexit
  623. @yes    stx editTask    ;We have a valid task now.
  624.  
  625. @atask    pha    ;Find out what control we are talking
  626.     pha    ;about.
  627.     _FindTargetCtl
  628.     ply
  629.     sty ctlHndl
  630.     ply
  631.     sty ctlHndl+2
  632.     bcs @secexit
  633.  
  634.     lda editTask    ;251 thru 254 (cut/copy/paste/clear)
  635.     stz editTask    ;This is also a flag, so we need to set
  636.     sec    ;it back.
  637.     sbc #251-4
  638.     asl a    ;Assume TextEdit.
  639.     tax
  640.     stz theHndl    
  641.     stz theHndl+2
  642.  
  643.     jsr getCtlProc    ;Find out what tool it is.
  644.     cmp #editTextControl>>16
  645.     beq @b    ;It is TextEdit, and the xreg is set up
  646.         ;for TextEdit.
  647.  
  648.     cmp #editLineControl>>16
  649.     bne @secexit    ;Not a LineEdit tool, so there can be
  650.         ;no cut/copy/paste.
  651.  
  652.     ldy #octlData    ;It is LineEdit.
  653.     lda [ctlPtr],y
  654.     sta theHndl
  655.     iny
  656.     iny
  657.     lda [ctlPtr],y
  658.     sta theHndl+2
  659.     txa
  660.     and #7
  661.     tax    ;LineEdit tool.
  662.  
  663. @b    pei theHndl+2    ;All the below routines will use this
  664.     pei theHndl    ;parameter eventually.
  665.     jmp (@theTask,x)
  666.  
  667. @theTask    dc.w @leCut, @leCopy, @lePaste, @leClear
  668.     dc.w @teCut, @teCopy, @tePaste, @teClear
  669.  
  670. @leCut    _LECut    ;Do the cut.
  671. @leCut0    lda flags
  672.     lsr a
  673.     bcs @clcexit
  674.     _ZeroScrap    ;Then conditionally do the LEToScrap.
  675.     pha    ;Conditionally, because of the bug for
  676.     _LEGetScrapLen    ;zero-length scrap.
  677.     pla
  678.     beq @clcexit
  679.     _LEToScrap
  680. @clcexit    clc
  681.     rts
  682. @clcexitz    pla
  683.     pla
  684.     clc
  685.     rts
  686.  
  687. @leCopy    _LECopy    ;Do the copy.
  688.     bra @leCut0
  689.  
  690. @lePaste    lda flags
  691.     lsr a
  692.     bcs @c
  693.  
  694.     pha    ;Boy, are we good citizens, or what?
  695.     pha
  696.     pei zero
  697.     _GetScrapSize
  698.     plx
  699.     ply
  700.     bcs @clcexitz    ;Give up and do nothing.
  701.     tya
  702.     bne @clcexitz    ;Way too big, so give up.
  703.     txa
  704.     beq @clcexitz    ;Too small, so give up.
  705.     _LEFromScrap
  706.     bcs @clcexitz    ;Somebody wasn't pleased, so give up.
  707. @c    _LEPaste
  708.     clc
  709.     rts
  710.  
  711. @leClear    _LEDelete    ;Do the clear.
  712.     clc
  713.     rts
  714.  
  715. @teCut    ldy #$28+2    ;Find out if we are read-only.
  716.     lda [ctlPtr],y
  717.     and #$0400    ;Bit 26, please.
  718.     beq @teCut0    ;Not read-only, so it is okay.
  719.     pla
  720.     pla
  721.     bra @teCut1
  722. @teCut0    _TECut    ;Do the cut.
  723. @teCut1    clc
  724.     rts
  725.  
  726. @teCopy    _TECopy    ;Do the copy.
  727.     clc
  728.     rts
  729.  
  730. @tePaste    _TEPaste    ;Do the paste.
  731.     clc
  732.     rts
  733.  
  734. @teClear    _TEClear    ;Do the clear.
  735.     clc
  736.     rts
  737.  
  738. getCtlProc    ldy #2    ;Find out what tool it is.
  739.     lda [ctlHndl],y
  740.     sta ctlPtr+2
  741.     lda [ctlHndl]
  742.     sta ctlPtr    ;Handle now dereferenced.
  743.     ldy #octlProc+2    ;Get hi-word of proc address.
  744.     lda [ctlPtr],y
  745.     rts
  746.  
  747. ***
  748.  
  749. doActivate    lda code
  750.     cmp #activateEvt
  751.     beq @a
  752.     sec
  753.     rts
  754.  
  755. @a    pha
  756.     pha
  757.     _GetPort
  758.  
  759.     pha    ;Result space for _GetWControls.
  760.     pha
  761.     ldy #omessage+2    ;Find out which window we are
  762.     lda [event],y    ;talking about.
  763.     tax
  764.     dey
  765.     dey
  766.     lda [event],y
  767.     phx
  768.     pha
  769.     phx
  770.     pha
  771.     _SetPort
  772.  
  773.     ldy #omodifiers    ;See if we are activating.
  774.     lda [event],y
  775.     lsr a
  776.     bcc @noMenuProc    ;We are not, so don't update menus.
  777.  
  778.     pha    ;See if we have a proc to set the state
  779.     pha    ;of the menus.
  780.     jsl fmdGetMenuProc
  781.     plx    ;Lo-word of address.
  782.     pla    ;Hi-word of address.
  783.     bne @haveMenuProc    ;We have a menu proc -- go do it.
  784.     txy
  785.     beq @noMenuProc    ;We don't have one.
  786.  
  787. @haveMenuProc    phk    ;Push where we want to return to.
  788.     pea @noMenuProc-1
  789.     xba    ;Push just the lo-byte as the hi-byte
  790.     pha    ;of ret addr.
  791.     phb
  792.     pla
  793.     dex    ;Push the lo-word minus 1 for rtl.
  794.     phx
  795.     rtl
  796.  
  797. @noMenuProc    _GetWControls
  798.     pla
  799.     sta ctlHndl
  800.     pla
  801.     sta ctlHndl+2
  802.  
  803. @loop    lda ctlHndl+1
  804.     beq @exit
  805.     jsr getCtlProc
  806.  
  807.     ldx #@nakend-@nak-2
  808. @naklook    cmp >@nak,x
  809.     beq @nextCtl
  810.     dex
  811.     dex
  812.     bpl @naklook
  813.  
  814.     cmp #editLineControl>>16
  815.     bne @inval    ;Invalidate unless lineEdit.
  816.         ;Invalidate this one selectively.  If
  817.         ;it is the window's target, then
  818.         ;invalidate it.
  819.  
  820.     ldy #octlMoreFlags
  821.     lda [ctlPtr],y
  822.     bpl @nextCtl    ;It doesn't need invalidating.
  823.  
  824. @inval    lda ctlPtr    ;Push pointer to bounding rect of ctl.
  825.     clc
  826.     adc #octlRect
  827.     tax
  828.     lda ctlPtr+2
  829.     adc #0
  830.     pha
  831.     phx
  832.     _InvalRect
  833.     jsr getCtlProc    ;An easy way to redereference.
  834.  
  835. @nextCtl    ldy #2
  836.     lda [ctlPtr]
  837.     sta ctlHndl
  838.     lda [ctlPtr],y
  839.     sta ctlHndl+2
  840.     bra @loop
  841.  
  842. @exit    _SetPort
  843.     clc    ;displayed in the correct state.
  844.     rts
  845.  
  846. @nak    dc.w $8100,$8900,$8D00 ;These don't need invalidating ever.
  847. @nakend
  848.  
  849. ***
  850.  
  851. doUpdate    lda code
  852.     cmp #updateEvt
  853.     beq @a
  854.     sec
  855.     rts    ;Event isn't an update event.
  856.  
  857. @noUpdate    stz code    ;We don't do this update, since the
  858.     clc    ;window that needs to be updated isn't
  859.     rts    ;the modal dialog.
  860.  
  861. @a    ldy #omessage+2    ;Find out which window we are
  862.     lda [event],y    ;talking about.
  863.     sta tempwptr+2
  864.     tax
  865.     dey
  866.     dey
  867.     lda [event],y
  868.     sta tempwptr
  869.     tay
  870.  
  871.     lda flags
  872.     and #fmdUpdateAll
  873.     bne @doUpdate    ;We are movable/modal, so update it,
  874.         ;whatever it is.
  875.  
  876.     cpy dlgwptr
  877.     bne @noUpdate    ;We are modal, so don't update other
  878.     cpx dlgwptr+2    ;windows.
  879.     bne @noUpdate    ;We are modal, so don't update other
  880.         ;windows.
  881.  
  882. @doUpdate    phx    ;Result space for _GetContentDraw.
  883.     phy
  884.     phx    ;For _GetContentDraw
  885.     phy
  886.     _GetContentDraw
  887.     plx
  888.     pla
  889.     bne @haveProc
  890.     txy
  891.     beq @exit
  892.  
  893. @haveProc    phk    ;Push return address for updateProc.
  894.     pea @retLoc-1
  895.  
  896.     xba    ;Push just the lo-byte as the hi-byte
  897.     pha    ;of ret addr.
  898.     phb
  899.     pla
  900.  
  901.     dex    ;Push the lo-word minus 1 for rtl.
  902.     phx
  903.  
  904.     pei tempwptr+2
  905.     pei tempwptr
  906.     _BeginUpdate
  907.  
  908.     rtl    ;Go to the updateProc.
  909.  
  910. @retLoc    pei tempwptr+2
  911.     pei tempwptr
  912.     _EndUpdate
  913.  
  914. @exit    clc
  915.     rts
  916.  
  917. ***
  918.  
  919. doMouseDown    lda code
  920.     cmp #mouseDownEvt
  921.     beq @a
  922.     sec
  923.     rts
  924.  
  925. @a    pha    ;Find out what window we clicked on.
  926.     pei zero
  927.     tdc
  928.     clc
  929.     adc #whichWindow
  930.     pha
  931.     ldy #owhere+2
  932.     lda [event],y
  933.     sta xloc
  934.     pha
  935.     dey
  936.     dey
  937.     lda [event],y
  938.     sta yloc
  939.     pha
  940.     _FindWindow
  941.     pla
  942.     bpl @aa
  943.  
  944.     tax    ;Keep it for _SystemClick's use.
  945.     lda flags
  946.     and #fmdDeskAcc
  947.     beq @toBeep
  948.  
  949.     pei event+2    ;Let the DA have some fun, too.
  950.     pei event
  951.     pei whichWindow+2
  952.     pei whichWindow
  953.     phx
  954.     _SystemClick
  955.     clc
  956.     rts
  957.  
  958. @aa    cmp #wInDrag
  959.     bne @b
  960.  
  961.     jsr isMyWindow    ;See if "whichWindow" equals dlgwptr.
  962.     bcc @toBeep    ;Wrong window -- nice try, though.
  963.  
  964.     lda flags
  965.     bpl @az    ;@noBeep
  966.  
  967.     ldy #0    ;Drag resolution -- default.
  968.     phy
  969.     pei xloc    ;Starting mouse location.
  970.     pei yloc
  971.     pea 8    ;TaskMaster uses this value, so we do.
  972.     phy    ;Default cursor boundary.
  973.     phy
  974.     pei dlgwptr+2
  975.     pei dlgwptr
  976.     _DragWindow
  977.     ldy #omodifiers
  978.     lda [event],y
  979.     and #appleKey
  980.     bne @az
  981.     pei dlgwptr+2
  982.     pei dlgwptr
  983.     _SelectWindow
  984. @az    brl @noBeep
  985.  
  986. @b    cmp #wInMenuBar
  987.     bne @c    ;Not in menu bar.
  988.     lda flags
  989.     lsr a
  990.     lsr a
  991.     bcc @toBeep    ;_MenuSelect not allowed -- go do beep.
  992.     lda flags
  993.     and #fmdMenuSelect+fmdMenuKey
  994.     beq @toBeep    ;Modal dialog, no menus allowed, so go
  995.         ;do beep.
  996.     brl doMenuTask    ;Movable/modal dialog, so go
  997.         ;handle menu bar.
  998.  
  999. @c    cmp #wInFrame    ;Don't beep if on dialog frame.  This
  1000.     beq @d    ;branch is the most efficient sizewise,
  1001.         ;since we won't hit any controls.
  1002.     cmp #wInContent
  1003.     bne @toBeep    ;We didn't click in a content.
  1004.  
  1005. @d    jsr isMyWindow
  1006.     bcs @e
  1007. @toBeep    brl @beep
  1008.  
  1009. @e    pha
  1010.     pha
  1011.     _FrontWindow
  1012.     pei dlgwptr+2
  1013.     pei dlgwptr
  1014.     _SelectWindow
  1015.  
  1016.     pla
  1017.     plx
  1018.     cmp whichWindow
  1019.     bne @noBeep
  1020.     cpx whichWindow+2
  1021.     bne @noBeep
  1022.  
  1023. @f    pha
  1024.     pei zero
  1025.     tdc
  1026.     clc
  1027.     adc #ctlHndl
  1028.     pha
  1029.     pei xloc
  1030.     pei yloc
  1031.     pei dlgwptr+2
  1032.     pei dlgwptr
  1033.     _FindControl
  1034.     pla
  1035.     beq @noBeep    ;Missed all of the controls.    
  1036.  
  1037.     jsr fixLEflash
  1038.  
  1039.     pha
  1040.     pei xloc
  1041.     pei yloc
  1042.     lda #-1
  1043.     pha
  1044.     pha
  1045.     pei ctlHndl+2
  1046.     pei ctlHndl
  1047.     _TrackControl
  1048.     pla
  1049.     sta >ctlPart
  1050.     beq @noBeep
  1051.  
  1052.     ldy #owmTaskData2    ;Put the found control in TaskData2
  1053.     lda ctlHndl    ;for application.
  1054.     sta [event],y
  1055.     iny
  1056.     iny
  1057.     lda ctlHndl+2
  1058.     sta [event],y
  1059.     jsr setValues
  1060.     clc
  1061.     rts
  1062.  
  1063. @beep    lda beepProc+2
  1064.     bmi @noBeep    ;Negative, do nothing.
  1065.     ora beepProc
  1066.     beq @sysBeep    ;Zero, regular SysBeep.
  1067.  
  1068.     pei event+2    ;Give the custom "beep" something
  1069.     pei event    ;to play with.
  1070.     phk    ;Push where we want to return to.
  1071.     pea @noBeep-1
  1072.     lda beepProc+1    ;Push updateProc addr and return to it.
  1073.     pha
  1074.     phb
  1075.     pla
  1076.     lda beepProc
  1077.     dec a
  1078.     pha
  1079.     rtl
  1080. @sysBeep    _SysBeep
  1081. @noBeep    clc
  1082.     rts
  1083.  
  1084. fixLEflash    jsr getCtlProc
  1085.     cmp #editLineControl>>16
  1086.     bne @rts
  1087.     ldy #octlMoreFlags
  1088.     lda [ctlPtr],y
  1089.     bmi @rts    ;LineEdit control already target.
  1090.  
  1091.     ldy #octlData    ;For lineEdit controls that are
  1092.     lda [ctlPtr],y    ;inactive, make sure that there is no
  1093.     sta theHndl    ;text currently selected.  If there is,
  1094.     iny    ;TrackControl will temporarily flash
  1095.     iny    ;the selected range.  So, we check to
  1096.     lda [ctlPtr],y    ;see if we are a lineEdit control.  If
  1097.     sta theHndl+2    ;we are, we see if we are active.  If
  1098.     ldy #2    ;we aren't, we set selEnd to be the
  1099.     lda [theHndl]    ;same as selStart.  Simple, huh?
  1100.     sta thePtr
  1101.     lda [theHndl],y
  1102.     sta thePtr+2
  1103.  
  1104.     ldy #oleSelStart    ;thePtr is deref'ed lineEdit record.
  1105.     lda [thePtr],y    ;Set selEnd to be the same as selStart.
  1106.     iny
  1107.     iny
  1108.     sta [thePtr],y    ;It is done.  It is good.  The end.
  1109.  
  1110. @rts    rts
  1111.  
  1112. ***
  1113.  
  1114. fmdGetCtlPart
  1115. FMDGETCTLPART    lda >ctlPart
  1116.     sta 4,s
  1117.     jml _fmdNoError
  1118. ctlPart    dc.w 0
  1119.  
  1120. ***
  1121.  
  1122. setValues    pha    ;Convert the control handle into an ID
  1123.     pha    ;for application.
  1124.     pei ctlHndl+2
  1125.     pei ctlHndl
  1126.     _GetCtlID
  1127.     pla
  1128.     ply
  1129.     bcs @a    ;List controls have non-super-control
  1130.         ;scrollbars.  We therefore don't want
  1131.         ;to return a control-id here, since
  1132.         ;non-super-controls don't have an id to
  1133.         ;return anyway.  (We get an error $1007
  1134.         ;if it isn't a super-control, so we
  1135.         ;don't want to return anything
  1136.         ;anything, since it garbage.)
  1137.     sta retval
  1138.     sty retval+2    ;Return the ctlID in retval.
  1139.  
  1140. @a    jsr getCtlProc    ;See if radio button or checkbox.
  1141.     cmp #radioControl>>16
  1142.     beq @radioButtonHit
  1143.     cmp #checkControl>>16
  1144.     bne @rts
  1145.  
  1146. @checkBoxHit    pha
  1147.     pei ctlHndl+2
  1148.     pei ctlHndl
  1149.     _GetCtlValue
  1150.     pla
  1151.     beq @c    ;Do a true NOT.
  1152.     lda #$FFFF
  1153. @c    inc a
  1154. @d    pha
  1155.     pei ctlHndl+2
  1156.     pei ctlHndl
  1157.     _SetCtlValue
  1158. @rts    rts
  1159.  
  1160. @radioButtonHit    lda #1
  1161.     bra @d
  1162.  
  1163. doMenuTask    clc
  1164. doMenuTaskz    php    ;Keep carry status.
  1165.     pei event+2
  1166.     pei event
  1167.     lda #0
  1168.     pha
  1169.     pha
  1170.     bcs @b
  1171.     jsr ibeamTest
  1172.     bcc @a
  1173.     _InitCursor    ;This only gets done if it is currently
  1174.         ;an ibeam.
  1175. @a    _MenuSelect    ;Handle the pullDown.
  1176.     bra @c
  1177. @b    _MenuKey    ;Handle the menu key.
  1178.  
  1179. @c    plp    ;Restore carry status.
  1180.     ldy #owmTaskData
  1181.     lda [event],y
  1182.     beq @rts    ;PullDown, cclear.  MenuKey, cset.
  1183.     tax
  1184.     iny
  1185.     iny
  1186.     lda [event],y
  1187.     sta menunum
  1188.  
  1189.     cpx #250    ;See if we should open a DA.
  1190.     bcs @d
  1191.  
  1192.     lda flags    ;See if we should handle DA's.
  1193.     and #fmdDeskAcc
  1194.     beq @y    ;No, so hilite menu to normal.
  1195.     phx    ;Open the can-o-worms.
  1196.     phx
  1197.     _InitCursor
  1198.     _OpenNDA
  1199.     pla
  1200.     bra @y    ;Do _HiliteMenu and leave.
  1201.  
  1202. @d    cpx #256    ;Anything above close, let app do it.
  1203.     bcs @z    ;Not an undo/cut/copy/paste/clear/close
  1204.         ;menu item.
  1205.  
  1206.     ldy wkind
  1207.     bpl @e
  1208.  
  1209.     cpx #255
  1210.     beq @closeNDA    ;Go let the DA handle it.
  1211.  
  1212.     txa
  1213.     sec
  1214.     sbc #249
  1215.     pha
  1216.     pha
  1217.     _SystemEdit
  1218.     pla
  1219.     bra @y    ;Do _HiliteMenu and leave.
  1220.  
  1221. @e    cpx #255
  1222.     beq @z    ;Let app do close for non DA windows.
  1223.     cpx #250
  1224.     beq @z    ;Let app do undo also.
  1225.  
  1226.     stx editTask    ;Let cut/copy/paste know what to do.
  1227.     jsr doCutCopyPaste
  1228.  
  1229. @y    pei zero
  1230.     pei menunum
  1231.     _HiliteMenu
  1232.     clc
  1233.     rts
  1234.  
  1235. @z    stx retval    ;Low-order word contains the ID # of
  1236.     ora #$8000    ;item selected.  Hi-order word contains
  1237.     sta retval+2    ;the menu ID # with hi-bit turned on.
  1238.     clc    ;The hi-bit is to allow the application
  1239.         ;to distinguish this from a control ID.
  1240.         ;This means ID's must be hi-bit off!!
  1241. @rts    rts
  1242.  
  1243. @closeNDA    pha
  1244.     pha
  1245.     _FrontWindow
  1246.     lda 1,s    ;Be extra paranoid -- it helps.
  1247.     cmp keepPort    ;Make sure that the desk accessory was
  1248.     bne @db    ;not active port when fakeModalDialog
  1249.     lda 3,s    ;was called.  If it is, we will get
  1250.     cmp keepPort+2    ;into trouble closing it, because we
  1251.     bne @db    ;will do a SetPort to keepPort when we
  1252.     lda dlgwptr    ;leave.  So, if keepPort is the port we
  1253.     sta keepPort    ;are about to close, change it to the
  1254.     lda dlgwptr+2    ;dlgwptr (the app's dialog window).
  1255.     sta keepPort+2
  1256. @db    _CloseNDAByWinPtr
  1257.     bra @y
  1258.  
  1259. isMyWindow    lda whichWindow
  1260.     cmp dlgwptr
  1261.     bne @no
  1262.     lda whichWindow+2
  1263.     cmp dlgwptr+2
  1264.     beq @yes
  1265. @no    clc
  1266. @yes    rts
  1267.  
  1268. ***
  1269.  
  1270. doMenuKey    lda code
  1271.     cmp #keyDownEvt
  1272.     beq @a
  1273.     sec
  1274. @rts    rts    ;It isn't a menu key, since it isn't
  1275.         ;even a key.
  1276.  
  1277. @a    lda flags
  1278.     and #fmdMenuKey
  1279.     sec
  1280.     beq @rts    ;Menu keys not allowed (carry is set).
  1281.  
  1282.     brl doMenuTaskz    ;Carry still set, which is important.
  1283.  
  1284. ***
  1285.  
  1286. ibeamTest    lda wkind
  1287.     clc
  1288.     bmi @rts    ;Don't do our ibeam when a DA is up.
  1289.     pha    ;This is so we know what cursor we
  1290.     pha    ;currently have.  Otherwise, we will be
  1291.     _GetCursorAdr    ;setting the cursor a lot, and it will
  1292.     pha    ;flash.
  1293.     pha
  1294.     jsl fmdGetIBeamAdr    ;This clears carry (no error returned.)
  1295.     pla
  1296.     ply
  1297.     eor 1,s
  1298.     bne @no    ;Carry is clear.
  1299.     tya
  1300.     eor 3,s
  1301.     bne @no    ;Carry is clear.
  1302.     sec
  1303. @no    pla
  1304.     pla
  1305. @rts    rts    ;Carry set means we now have ibeam.
  1306.  
  1307.     ENDP
  1308.  
  1309.  
  1310. *******************************************************************************
  1311. *******************************************************************************
  1312. *******************************************************************************
  1313.  
  1314. * From this point are additional entry points and useful access routines.
  1315.  
  1316. ********************
  1317.  
  1318.     export fmdStdDrawProc
  1319. fmdStdDrawProc    PROC
  1320.     export FMDSTDDRAWPROC
  1321.  
  1322. FMDSTDDRAWPROC    pha    ;What kind of window frame do we want?
  1323.     pha
  1324.     pha
  1325.     _GetPort
  1326.     _GetWFrame
  1327.     pla    ;fAlert is bit 13.  fFlex is bit 9.
  1328.     asl a
  1329.     asl a    ;fAlert is now in bit 15.
  1330.     bmi @noFrame    ;We already have a frame, and
  1331.         ;it looks maaahvelous!
  1332.  
  1333.     and #$0800    ;Bit 9 moved into bit 11.
  1334.     bne @noFrame
  1335.  
  1336.     pha
  1337.     _GetMasterSCB
  1338.     pla
  1339.     xba
  1340.     asl a
  1341.     lda #5
  1342.     bcs @in640
  1343.     lsr a
  1344. @in640    pha    ;Keep the width for _InsetRect.
  1345.     pha    ;Push the width for _FrameRect.
  1346.     pea 2
  1347.     _SetPenSize
  1348.     plx    ;The width for _InsetRect.
  1349.     lda #@workRect
  1350.     ldy #@workRect>>16
  1351.     phy    ;Push parameters for _FrameRect.
  1352.     pha
  1353.     phy    ;Push parameters for _InsetRect.
  1354.     pha
  1355.     phx    ;Push the width for _InsetRect.
  1356.     pea 2
  1357.     phy    ;Push parameters for _GetPortRect.
  1358.     pha
  1359.     _GetPortRect
  1360.     _InsetRect
  1361.     _FrameRect
  1362.     _PenNormal
  1363.  
  1364. @noFrame    pha
  1365.     pha
  1366.     _GetPort
  1367.     _DrawControls
  1368.     rtl
  1369.  
  1370. @workRect    ds.w 4
  1371.  
  1372.     ENDP
  1373.  
  1374. ********************
  1375.  
  1376.     export fmdSetMenuProc
  1377. fmdSetMenuProc    PROC
  1378.     export FMDSETMENUPROC
  1379.     export fmdGetMenuProc, FMDGETMENUPROC
  1380.     import _fmdNoError
  1381.  
  1382. FMDSETMENUPROC    lda 4,s
  1383.     sta >menuProc
  1384.     lda 6,s
  1385.     sta >menuProc+2
  1386.     lda 1,s
  1387.     sta 5,s
  1388.     lda 2,s
  1389.     sta 6,s
  1390.     pla
  1391.     pla
  1392. exit    jml _fmdNoError
  1393.  
  1394. fmdGetMenuProc
  1395. FMDGETMENUPROC    lda >menuProc
  1396.     sta 4,s
  1397.     lda >menuProc+2
  1398.     sta 6,s
  1399.     bra exit
  1400.  
  1401. menuProc    dc.l 0
  1402.  
  1403.     ENDP
  1404.  
  1405. ********************
  1406.  
  1407.     export fmdEditMenu
  1408. fmdEditMenu    PROC
  1409.     export FMDEDITMENU
  1410.     import _fmdNoError
  1411.  
  1412.     DefineStack
  1413.  
  1414. selStart    long
  1415. selEnd    long
  1416. leHndl    long
  1417. lePtr    long
  1418. ctlPtr    long    ;Must be 2nd from end of local space.
  1419. ctlHndl    long    ;Must be at end of local space.
  1420.  
  1421. sizeLocals    EndLocals
  1422.  
  1423. saveDPage    word
  1424. returnAddr    block 3
  1425.  
  1426. ***
  1427.  
  1428. FMDEDITMENU    phd    ;Save directPage register.
  1429.  
  1430.     tsc    ;Make space for locals, part 1.
  1431.     sec
  1432.     sbc #sizeLocals
  1433.     tcd
  1434.  
  1435.     pha    ;Find out if it is a DA window.
  1436.     pha
  1437.     pha
  1438.     _FrontWindow
  1439.     _GetWKind
  1440.     pla
  1441.     bpl @a    ;It is a regular window.
  1442.     pea 250
  1443.     _EnableMItem    ;Enable undo.
  1444.     pea 255
  1445.     _EnableMItem    ;Enable close.
  1446.     ldx #%1111    ;Enable cut/copy/paste/clear.
  1447.     brl @setMenus
  1448.  
  1449. @a    pha
  1450.     pha
  1451.     _FindTargetCtl
  1452.     bcc @aa    ;There is a target, so go do some work.
  1453.     brl @noTool
  1454.  
  1455. @aa    ldy #2    ;Deref target ctl handle into ctlPtr.
  1456.     lda [ctlHndl],y
  1457.     pha
  1458.     lda [ctlHndl]
  1459.     pha
  1460.  
  1461.     tdc    ;Make space for locals, part 2.
  1462.     tcs    ;Stack ptr & directPage ptr agree now.
  1463.  
  1464.     ldy #octlProc+2    ;Get hi-word of proc address.
  1465.     lda [ctlPtr],y
  1466.  
  1467.  
  1468.     cmp #editTextControl>>16
  1469.     beq @textEdit    ;It is TextEdit tool.
  1470.     cmp #editLineControl>>16
  1471.     bne @noTool    ;Not LineEdit tool.
  1472.  
  1473. @lineEdit    ldy #octlData    ;Get the lineEdit handle from
  1474.     lda [ctlPtr],y    ;the control's data field.
  1475.     sta leHndl
  1476.     iny
  1477.     iny
  1478.     lda [ctlPtr],y
  1479.     sta leHndl+2
  1480.  
  1481.     ldy #2    ;Dereference leHndl.
  1482.     lda [leHndl]
  1483.     sta lePtr
  1484.     lda [leHndl],y
  1485.     sta lePtr+2
  1486.  
  1487.     ldx #0
  1488.     jsr canWePaste
  1489.  
  1490.     ldy #oleSelStart
  1491.     lda [lePtr],y
  1492.     iny
  1493.     iny
  1494.     cmp [lePtr],y
  1495.     beq @setMenus
  1496.     txa
  1497.     ora #%1011    ;Enable cut/copy/clear.
  1498.     tax    
  1499.     bra @setMenus
  1500.  
  1501. @textEdit    ldy #0
  1502.     phy
  1503.     tdc
  1504.     clc
  1505.     adc #selStart
  1506.     pha
  1507.     phy
  1508.     adc #selEnd-selStart
  1509.     pha
  1510.     pei ctlHndl+2
  1511.     pei ctlHndl
  1512.     _TEGetSelection
  1513.     ldx #%1011
  1514.     lda selStart
  1515.     cmp selEnd
  1516.     bne @hasSelect
  1517.     lda selStart+2
  1518.     cmp selEnd+2
  1519.     bne @hasSelect
  1520.     ldx #0
  1521.  
  1522. @hasSelect    jsr canWePaste
  1523.  
  1524.     ldy #$28+2    ;Find out if we are read-only.
  1525.     lda [ctlPtr],y
  1526.     and #$0400    ;Bit 26, please.
  1527.     beq @setMenus
  1528.  
  1529.     txa    ;Don't allow cut & paste.
  1530.     and #2
  1531.     tax
  1532.     bra @setMenus
  1533.  
  1534. @noTool    ldx #0    ;Bit 0 for cut, 1 for copy,
  1535.         ;2 for paste.
  1536. @setMenus    txa
  1537.     ldy #251
  1538.     jsr setOneMenu
  1539.     jsr setOneMenu
  1540.     jsr setOneMenu
  1541.     jsr setOneMenu
  1542.  
  1543. @exit    tdc    ;Remove local space.
  1544.     clc
  1545.     adc #sizeLocals
  1546.     tcs
  1547.     pld    ;Restore directPage register.
  1548.     jml _fmdNoError
  1549.  
  1550. setOneMenu    lsr a
  1551.     pha
  1552.     phy
  1553.     phy
  1554.     bcs @enable
  1555. @disable    _DisableMItem
  1556.     bra @a
  1557. @enable    _EnableMItem
  1558. @a    ply
  1559.     iny
  1560.     pla
  1561.     rts
  1562.  
  1563. canWePaste    txa    ;Assume no paste.
  1564.     and #$FFFF-4
  1565.     pha
  1566.  
  1567.     pha    ;See if paste should be available.
  1568.     pha
  1569.     pea 0
  1570.     _GetScrapSize
  1571.     plx
  1572.     ply
  1573.  
  1574.     pla    ;Get cut/copy/paste status back.
  1575.  
  1576.     bcs @exit    ;Error, so no paste.
  1577.     phy
  1578.     ply
  1579.     bne @yes
  1580.     txy
  1581.     beq @exit
  1582. @yes    ora #4
  1583.  
  1584. @exit    tax
  1585.     rts
  1586.  
  1587.     ENDP
  1588.  
  1589. ********************
  1590.  
  1591.     export fmdFindCursorCtl
  1592. fmdFindCursorCtl    PROC
  1593.     export FMDFINDCURSORCTL
  1594.     import _fmdNoError
  1595.  
  1596.     DefineStack
  1597.  
  1598. hndl    long    ;Must be at 1,s
  1599. ctlHndl    long
  1600. ctlPtr    long
  1601.  
  1602. sizeLocals    EndLocals
  1603.  
  1604. saveDPage    word
  1605. returnAddr    block 3
  1606.  
  1607.     BegParms
  1608. wptr    long
  1609. yloc    word
  1610. xloc    word
  1611. ctlHndlPtr    long    ;Where to store the control handle.
  1612. sizeParms    EndParms
  1613.  
  1614. ctlPart    word
  1615.  
  1616. ***
  1617.  
  1618. FMDFINDCURSORCTL    phd    ;Save directPage register.
  1619.     tsc    ;Make space for locals.
  1620.     sec
  1621.     sbc #sizeLocals
  1622.     tcs
  1623.     tcd    ;Set directPage register.
  1624.  
  1625.     pei wptr+2
  1626.     pei wptr
  1627.     _GetWControls    ;Result space already there (hndl).
  1628.  
  1629.     stz ctlPart    ;Assume failure.
  1630.     stz ctlHndl
  1631.     stz ctlHndl+2
  1632.  
  1633. @loop    lda hndl+1
  1634.     beq @exit    ;No more controls to check.
  1635.  
  1636.     ldy #2    ;Deref hndl.
  1637.     lda [hndl]
  1638.     sta ctlPtr
  1639.     lda [hndl],y
  1640.     sta ctlPtr+2
  1641.  
  1642.     pha    ;Result space for _PtInRect
  1643.     pea 0    ;Push pointer to point.
  1644.     tdc
  1645.     clc
  1646.     adc #yloc
  1647.     pha
  1648.     lda ctlPtr    ;Push ptr to bounding rect of ctl.
  1649.     clc
  1650.     adc #octlRect
  1651.     tax
  1652.     lda ctlPtr+2
  1653.     adc #0
  1654.     pha
  1655.     phx
  1656.     _PtInRect
  1657.     pla
  1658.     beq @nextCtl
  1659.  
  1660.     sta ctlPart
  1661.     lda hndl    ;Copy the temp hndl to the "real" one.
  1662.     sta ctlHndl
  1663.     lda hndl+2
  1664.     sta ctlHndl+2
  1665.  
  1666.     ldy #octlProc+2    ;Get hi-word of proc address.
  1667.     lda [ctlPtr],y
  1668.     cmp #editTextControl>>16
  1669.     bne @exit
  1670.  
  1671. @nextCtl    ldy #2
  1672.     lda [ctlPtr]    ;Get the next control handle.
  1673.     sta hndl
  1674.     lda [ctlPtr],y
  1675.     sta hndl+2
  1676.     bra @loop
  1677.  
  1678. @exit    lda ctlHndl    ;Return the ctl hndl (could be NULL).
  1679.     sta [ctlHndlPtr]
  1680.     lda ctlHndl+2
  1681.     ldy #2
  1682.     sta [ctlHndlPtr],y
  1683.  
  1684.     tsc    ;Get rid of local variables.
  1685.     clc
  1686.     adc #sizeLocals
  1687.     tcs
  1688.     pld    ;Restore directPage register.
  1689.     lda 1,s    ;Move return address.
  1690.     sta 1+sizeParms,s
  1691.     lda 2,s
  1692.     sta 2+sizeParms,s
  1693.     tsc    ;Get rid of passed parameters.
  1694.     adc #sizeParms
  1695.     tcs
  1696.     jml _fmdNoError
  1697.  
  1698.     ENDP
  1699.  
  1700. ********************
  1701.  
  1702. * Here are some useful routines for control information access via a ctl ID.
  1703.  
  1704. ********************
  1705.  
  1706. * This routine takes a window pointer, a lineEdit control ID, and a pointer to
  1707. * a pascal string.  It stuffs the pascal string into the lineEdit control.
  1708. * It also select the full range of the text.  This is useful because the
  1709. * target control should have all the text selected when a dialog comes up.
  1710. * Doing it here means you don't have to do it elsewhere.
  1711.  
  1712.     export fmdLESetText
  1713. fmdLESetText    PROC
  1714.     export FMDLESETTEXT
  1715.     export fmdLEGetText, FMDLEGETTEXT
  1716.     import _fmdSetError
  1717.  
  1718.     DefineStack
  1719.  
  1720. ctlHndl    long
  1721. ctlPtr    long
  1722. leHndl    long
  1723. lePtr    long
  1724. lineHndl    long
  1725. linePtr    long
  1726. cstr    long
  1727. lineLength    word
  1728. rect    block 8    ;Must be > oleViewRect ($10)
  1729.  
  1730. sizeLocals    EndLocals
  1731.  
  1732. saveDPage    word
  1733. returnAddr    block 3
  1734.  
  1735.     BegParms
  1736. pstr    long    ;Pointer to string space.
  1737. lineEditID    long    ;ID of lineEdit control.
  1738. wptr    long    ;Window that owns the control.
  1739. sizeParms    EndParms
  1740.  
  1741. ***
  1742.  
  1743. FMDLESETTEXT    jsr lineEditSetup    ;Set up everything we need.
  1744.     bcs exit    ;Couldn't dereference for some reason.
  1745.  
  1746.     pei cstr+2    ;Set text to c-string.
  1747.     pei cstr
  1748.     lda [pstr]    ;Get length of pascal string.
  1749.     and #$FF
  1750.     pha
  1751.     pei leHndl+2
  1752.     pei leHndl
  1753.     _LESetText
  1754.     bcs exit
  1755.  
  1756.     pha    ;Invalidate view rect of lineEdit.
  1757.     pha
  1758.     _GetPort    ;Save the current port.
  1759.     pei wptr+2
  1760.     pei wptr
  1761.     _SetPort    ;Make the window the current port
  1762.         ;(for _InvalRect).
  1763.  
  1764.     jsr lineEditDeref    ;Redereference -- slow but small.
  1765.     ldy #oleSelStart
  1766.     lda #0
  1767.     pha    ;Hi-word for _InvalRect.
  1768.     sta [lePtr],y
  1769.     iny
  1770.     iny    ;Point at leSelEnd.
  1771.     lda [pstr]    ;Get length of pascal string.
  1772.     and #$FF
  1773.     sta [lePtr],y
  1774.  
  1775.     ldy #oleViewRect+6    ;Copy lineEdit viewRect into rect.
  1776. @a    lda [lePtr],y
  1777.     tyx
  1778.     sta <rect-oleViewRect,x
  1779.     dey
  1780.     dey
  1781.     cpy #oleViewRect
  1782.     bcs @a
  1783.  
  1784.     tdc    ;Hi-word alreay on stack.  (It's a 0).
  1785.     adc #rect    ;Carry still clear.
  1786.     pha
  1787.     _InvalRect    ;Inval that rect.
  1788.  
  1789.     _SetPort    ;Put the port back.
  1790.  
  1791. exitNoErr    lda #0    ;Return no error.
  1792. exit    tay    ;Save error code.
  1793.  
  1794.     tdc    ;Get rid of local variables.
  1795.     clc
  1796.     adc #sizeLocals
  1797.     tcs
  1798.     pld    ;Restore directPage register.
  1799.  
  1800.     lda 1,s    ;Move return address.
  1801.     sta 1+sizeParms,s
  1802.     lda 2,s
  1803.     sta 2+sizeParms,s
  1804.  
  1805.     tsc    ;Pull passed parms off stack.
  1806.     adc #sizeParms
  1807.     tcs
  1808.  
  1809.     tya    ;Recover error code.
  1810.     jml _fmdSetError
  1811.  
  1812. ***
  1813.  
  1814. fmdLEGetText
  1815. FMDLEGETTEXT    jsr lineEditSetup    ;Set up everything we need.
  1816.     bcs exit    ;Couldn't dereference for some reason.
  1817.  
  1818.     pei linePtr+2    ;Copy the text into the string.
  1819.     pei linePtr
  1820.     pei cstr+2
  1821.     pei cstr
  1822.     pea 0
  1823.     pei lineLength
  1824.     _BlockMove
  1825.  
  1826.     ldy lineLength    ;Store the p-string length and also
  1827.     tya    ;terminate the string for the c dudes.
  1828.     shortm    ;Use 8-bit accumulator.
  1829.     sta [pstr]    ;Save the p-string length byte.
  1830.     lda #0
  1831.     sta [cstr],y    ;Terminate the c-string.
  1832.     longm    ;Set accumulator back to 16-bit.
  1833.  
  1834.     bra exitNoErr    ;Return no error.
  1835.  
  1836. ***
  1837.  
  1838. lineEditSetup    plx    ;Save return address so stack frame
  1839.         ;setup works.
  1840.  
  1841.     phd    ;Save directPage register.
  1842.     tsc    ;Make space for locals.
  1843.     sec
  1844.     sbc #sizeLocals
  1845.     tcs
  1846.     tcd    ;Set directPage register.
  1847.  
  1848.     phx    ;Put return address back.
  1849.  
  1850.     lda pstr    ;Also point past p-string length
  1851.     ldx pstr+2    ;for c-strings.
  1852.     inc a
  1853.     bne @a
  1854.     inx
  1855. @a    sta cstr
  1856.     stx cstr+2
  1857.  
  1858.     pha    ;Get the control handle via wptr,id.
  1859.     pha
  1860.     pei wptr+2
  1861.     pei wptr
  1862.     pei lineEditID+2
  1863.     pei lineEditID
  1864.     _GetCtlHandleFromID
  1865.     plx
  1866.     stx ctlHndl
  1867.     plx
  1868.     stx ctlHndl+2
  1869.     bcs rts1
  1870.  
  1871.     ldy #2    ;Dereference ctlHndl.
  1872.     lda [ctlHndl]
  1873.     sta ctlPtr
  1874.     lda [ctlHndl],y
  1875.     sta ctlPtr+2
  1876.  
  1877.     ldy #octlData    ;Get the lineEdit handle from
  1878.     lda [ctlPtr],y    ;the control's data field.
  1879.     sta leHndl
  1880.     iny
  1881.     iny
  1882.     lda [ctlPtr],y
  1883.     sta leHndl+2
  1884.  
  1885. lineEditDeref    ldy #2    ;Dereference leHndl.
  1886.     lda [leHndl]
  1887.     sta lePtr
  1888.     lda [leHndl],y
  1889.     sta lePtr+2
  1890.  
  1891.     ldy #oleLength
  1892.     lda [lePtr],y
  1893.     sta lineLength
  1894.  
  1895.     ldy #oleLineHandle
  1896.     lda [lePtr],y
  1897.     sta lineHndl
  1898.     iny
  1899.     iny
  1900.     lda [lePtr],y
  1901.     sta lineHndl+2
  1902.  
  1903.     ldy #2    ;Dereference lineHndl.
  1904.     lda [lineHndl]
  1905.     sta linePtr
  1906.     lda [lineHndl],y
  1907.     sta linePtr+2
  1908.     clc    ;Everything worked.
  1909.  
  1910. rts1    rts
  1911.  
  1912.     ENDP
  1913.  
  1914. ********************
  1915.  
  1916.     export fmdWhichRadio
  1917. fmdWhichRadio    PROC
  1918.     export FMDWHICHRADIO
  1919.     import _fmdSetError
  1920.  
  1921.     DefineStack
  1922.  
  1923. ctlHndl    long    ;Must be at 1,s
  1924. ctlPtr    long
  1925. ctlID    long    ;ID of some radio button control.
  1926. theRadBut    word
  1927. notHere    word    ;Flag for active button not found.
  1928.  
  1929. sizeLocals    EndLocals
  1930.  
  1931. saveDPage    word
  1932. returnAddr    block 3
  1933.  
  1934.     BegParms
  1935. famNum    word
  1936. wptr    long    ;Window that owns the control.
  1937. sizeParms    EndParms
  1938.  
  1939. radioNum    word
  1940.  
  1941. ***
  1942.  
  1943. FMDWHICHRADIO    phd    ;Save directPage register.
  1944.     tsc    ;Make space for locals.
  1945.     sec
  1946.     sbc #sizeLocals
  1947.     tcs
  1948.     tcd    ;Set directPage register.
  1949.  
  1950.     lda #$FFFF    ;This is supposed to be a bogus value
  1951.     sta radioNum    ;(0 is legit).
  1952.     sta notHere    ;Assume we won't find active radio
  1953.     sta ctlID+2    ;button of correct family number.
  1954.  
  1955.     pei wptr+2
  1956.     pei wptr
  1957.     _GetWControls    ;Result space already there (ctlHndl).
  1958.     bcs @exit
  1959.  
  1960. @loop    lda ctlHndl+1    ;See if we have a NULL handle yet.
  1961.     beq @endLoop
  1962.  
  1963.     jsr @derefCtl    ;Deref ctlHndl into ctlPtr.
  1964.  
  1965.     ldy #octlProc+2    ;Get hi-word of proc address.
  1966.     lda [ctlPtr],y
  1967.     cmp #radioControl>>16
  1968.     bne @nextCtl    ;Not a radio button.  Skip it.
  1969.  
  1970.     ldy #octlFlag
  1971.     lda [ctlPtr],y
  1972.     and #$7F
  1973.     cmp famNum    ;See if it is "our" family.
  1974.     bne @nextCtl    ;Not related.
  1975.  
  1976.     ldy #octlID+2    ;See if this is the smallest ctlID for
  1977.     lda [ctlPtr],y    ;our family yet.
  1978.     tax
  1979.     dey
  1980.     dey
  1981.     lda [ctlPtr],y
  1982.     cpx ctlID+2
  1983.     bcc @smaller
  1984.     bne @a    ;It isn't.
  1985.     cmp ctlID
  1986.     bcs @a    ;It isn't.
  1987. @smaller    sta ctlID    ;It is, so remember it.
  1988.     stx ctlID+2
  1989.  
  1990. @a    tax
  1991.     ldy #octlValue
  1992.     lda [ctlPtr],y
  1993.     beq @nextCtl    ;This isn't the active radio button.
  1994.     stx theRadBut    ;This is the one, so remember enough
  1995.     stz notHere    ;of it.  Also, flag we found it.
  1996.  
  1997. @nextCtl    ldy #2
  1998.     lda [ctlPtr]
  1999.     sta ctlHndl
  2000.     lda [ctlPtr],y
  2001.     sta ctlHndl+2
  2002.     bra @loop
  2003.  
  2004. @endLoop    lda notHere    ;See if we found it.  If we didn't,
  2005.     bmi @b    ;return $FFFF to indicate this.
  2006.     lda theRadBut
  2007.     sec
  2008.     sbc ctlID
  2009. @b    sta radioNum    ;This is what the programmer was
  2010.         ;yearning for.
  2011.  
  2012.     lda #0    ;Return no error.
  2013.  
  2014. @exit    tay    ;Save error code.
  2015.  
  2016.     tdc    ;Get rid of local variables.
  2017.     clc
  2018.     adc #sizeLocals
  2019.     tcs
  2020.     pld    ;Restore directPage register.
  2021.  
  2022.     lda 1,s    ;Move return address.
  2023.     sta 1+sizeParms,s
  2024.     lda 2,s
  2025.     sta 2+sizeParms,s
  2026.  
  2027.     tsc    ;Pull passed parms off stack.
  2028.     adc #sizeParms
  2029.     tcs
  2030.  
  2031.     tya    ;Recover error code.
  2032.     jml _fmdSetError
  2033.  
  2034. @derefCtl    ldy #2
  2035.     lda [ctlHndl]
  2036.     sta ctlPtr
  2037.     lda [ctlHndl],y
  2038.     sta ctlPtr+2
  2039.     rts
  2040.  
  2041.     ENDP
  2042.  
  2043. ********************
  2044.  
  2045.     export fmdIBeamCursor
  2046. fmdIBeamCursor    PROC
  2047.     export FMDIBEAMCURSOR
  2048.     export fmdInitIBeam, fmdGetIBeamAdr, fmdSetIBeam
  2049.     export FMDINITIBEAM, FMDGETIBEAMADR, FMDSETIBEAM
  2050.     import _fmdNoError
  2051.  
  2052. FMDIBEAMCURSOR    lda >curIBeam+2    ;Change the cursor to current ibeam.
  2053.     pha
  2054.     lda >curIBeam
  2055.     pha
  2056.     _SetCursor
  2057.     bra exit
  2058.  
  2059. fmdInitIBeam
  2060. FMDINITIBEAM    lda #ibeamCursor    ;Make default ibeam current ibeam.
  2061.     sta >curIBeam
  2062.     lda #ibeamCursor>>16
  2063.     sta >curIBeam+2
  2064.     bra exit
  2065.  
  2066. fmdGetIBeamAdr
  2067. FMDGETIBEAMADR    lda >curIBeam    ;Return address of current ibeam.
  2068.     sta 4,s
  2069.     lda >curIBeam+2
  2070.     sta 6,s
  2071.     bra exit
  2072.  
  2073. fmdSetIBeam
  2074. FMDSETIBEAM    lda 4,s    ;Change the ibeam to alternate ibeam.
  2075.     sta >curIBeam
  2076.     lda 6,s
  2077.     sta >curIBeam+2
  2078.     lda 1,s
  2079.     sta 5,s
  2080.     lda 2,s
  2081.     sta 6,s
  2082.     pla
  2083.     pla
  2084. exit    jml _fmdNoError
  2085.  
  2086. curIBeam    dc.l 0
  2087. ibeamCursor    dc.b 9,0,3,0
  2088.     dc.b $00,$F0,$F0,$00,$00,$00
  2089.     dc.b $00,$0F,$00,$00,$00,$00
  2090.     dc.b $00,$0F,$00,$00,$00,$00
  2091.     dc.b $00,$0F,$00,$00,$00,$00
  2092.     dc.b $00,$0F,$00,$00,$00,$00
  2093.     dc.b $00,$0F,$00,$00,$00,$00
  2094.     dc.b $00,$0F,$00,$00,$00,$00
  2095.     dc.b $00,$0F,$00,$00,$00,$00
  2096.     dc.b $00,$F0,$F0,$00,$00,$00
  2097.         
  2098.     dc.b $00,$00,$00,$00,$00,$00
  2099.     dc.b $00,$00,$00,$00,$00,$00
  2100.     dc.b $00,$00,$00,$00,$00,$00
  2101.     dc.b $00,$00,$00,$00,$00,$00
  2102.     dc.b $00,$00,$00,$00,$00,$00
  2103.     dc.b $00,$00,$00,$00,$00,$00
  2104.     dc.b $00,$00,$00,$00,$00,$00
  2105.     dc.b $00,$00,$00,$00,$00,$00
  2106.     dc.b $00,$00,$00,$00,$00,$00
  2107.     dc.b 4,0,6,0
  2108.  
  2109.     ENDP
  2110.  
  2111. ********************
  2112.  
  2113.     export fmdStartUp
  2114. fmdStartUp    PROC
  2115.     export FMDSTARTUP
  2116.  
  2117. FMDSTARTUP    lda #0
  2118.     pha
  2119.     pha
  2120.     jsl fmdSetMenuProc
  2121.     jml fmdInitIBeam
  2122.  
  2123.     ENDP
  2124.  
  2125. ********************
  2126.  
  2127.     export fmdShutDown
  2128. fmdShutDown    PROC
  2129.     export FMDSHUTDOWN
  2130.     import _fmdNoError
  2131.  
  2132. FMDSHUTDOWN    jml _fmdNoError
  2133.  
  2134.     ENDP
  2135.  
  2136. ********************
  2137.  
  2138.     export _fmdNoError
  2139. _fmdNoError    PROC
  2140.     export _fmdSetError, fmdGetError
  2141.  
  2142.     lda #0
  2143.  
  2144. _fmdSetError    sta >fmdErr
  2145.     bra exit
  2146.  
  2147. fmdGetError    lda >fmdErr
  2148.     sta 4,s
  2149. exit    cmp #1
  2150.     rtl
  2151.  
  2152. fmdErr    dc.w 0
  2153.  
  2154.     ENDP
  2155.  
  2156. ********************
  2157.  
  2158.     END